package com.tender.utils;

import com.tender.constants.Constants;
import com.tender.enums.ErrorTypeEnum;
import lombok.Data;

@Data
public class Result<T> {

    // 是否成功，默认 success
    private boolean success = true;

    // 业务数据 <泛型>
    private T data;

    // 业务请求ID
    private String reqMsgId;

    // 响应编码
    private String resultCode;

    // 响应说明
    private String resultMsg;

    private Result(T data, boolean success) {
        this.data = data;
        this.success = success;
        this.resultCode = Constants.OK;
    }

    private Result(ErrorTypeEnum errorTypeEnum) {
        this.success = false;
        if (null != errorTypeEnum) {
            this.resultCode = errorTypeEnum.getErrorCode();
            this.resultMsg = errorTypeEnum.getErrorMsgCn();
        }
    }

    private Result(String errorMsgCn) {
        this.success = false;
        this.resultMsg = errorMsgCn;
        this.resultCode = Constants.FAIL;
    }

    private Result(ErrorTypeEnum errorTypeEnum, String... args) {
        this.success = true;
        if (null != errorTypeEnum) {
            this.resultCode = errorTypeEnum.getErrorCode();
            this.resultMsg = String.format(errorTypeEnum.getErrorMsgCn(), args);
        }
    }

    public static <T> Result<T> of() {
        return new Result<>(null, true);
    }

    public static <T> Result<T> of(T data) {
        return null == data ? ofNull() : new Result<>(data, true);
    }

    public static <T> Result<T> of(T data, String resultMsg) {
        if (null == data) {
            return ofNull();
        }

        Result<T> result = new Result<>(data, true);
        result.setResultMsg(resultMsg);
        return result;
    }

    public static <T> Result<T> ofErrorType(ErrorTypeEnum errorType) {
        return new Result<>(errorType);
    }

    public static <T> Result<T> ofErrorType(ErrorTypeEnum errorType, String... arrs) {
        return new Result<>(errorType, arrs);
    }

    public static <T> Result<T> ofErrorMessage(String errorMessage) {
        return new Result<>(errorMessage);
    }


    public static <T> Result<T> ofNull() {
        return new Result<>(null, true);
    }

}
